package com.aura.common.redis.service;

import com.aura.common.core.utils.JsonUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName RedisStringService
 * @Description
 * @Author ZJX
 * @Date 2025/7/19 23:52
 * @Version 1.0
 **/
@Component
@SuppressWarnings(value = {"unchecked", "rawtypes"})
public class RedisStringService {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 缓存String数据 （将数据转为Json字符串存入）
     *
     * @param key 缓存的键值
     * @param value 缓存的值
     * @param <T> 对象类型
     */
    public <T> void setCacheObject(final String key, final T value) {
        redisTemplate.opsForValue().set(key,value);
    }


    /**
     * 缓存String数据，并设置有效时间 （将数据转为Json字符串存入）
     * @param key 缓存的键值
     * @param value 缓存的值
     * @param timeout 时间
     * @param timeUnit 时间单位
     * @param <T> 对象类型
     */
    public <T> void setCacheObject(final String key, final T value, final long timeout, final TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key,value,timeout,timeUnit);
    }


    /**
     * 缓存String数据，如果该键不存在则存储，若已存在则不存储。
     *
     * @param key      缓存的键值
     * @param value    缓存的值
     * @param <T> 对象类型
     * @return 是否缓存了对象   如果key已经存在，则返回false，否则返回true
     */
    public <T> boolean setCacheObjectIfAbsent(final String key, final T value){
        return redisTemplate.opsForValue().setIfAbsent(key,value);
    }


    /**
     * 缓存String数据，如果该键不存在则存储,并设置数据有效时间，若已存在则不存储。
     *
     * @param key      缓存的键值
     * @param value    缓存的值
     * @param timeout  时间
     * @param timeUnit 时间单位
     * @param <T> 对象类型
     * @return 是否缓存了对象   如果key已经存在，则返回false，否则返回true
     */
    public <T> boolean setCacheObjectIfAbsent(final String key, final T value,final long timeout,TimeUnit timeUnit){
        return redisTemplate.opsForValue().setIfAbsent(key,value,timeout,timeUnit);
    }

    /**
     * 获得缓存的数据（将缓存的数据反序列化为指定类型返回）
     * @param key 缓存键值
     * @param clazz 对应数据的类
     * @return 缓存键值对应的数据
     * @param <T> 对应数据的类型
     */
    public <T> T getCacheObject(final String key, final Class<T> clazz){
        Object object = redisTemplate.opsForValue().get(key);
        if (object == null){
            return null;
        }
        String jsonStr = JsonUtil.obj2String(object);
        return JsonUtil.string2Obj(jsonStr,clazz);
    }

    /**
     * 获得缓存的数据 （将缓存的数据反序列化为指定类型返回，支持复杂的泛型）
     * @param key 缓存键值
     * @param valueTypeRef 类型模板
     * @return 缓存键值对应的数据
     * @param <T> 对象类型
     */
    public <T> T getCacheObject(final String key, TypeReference<T> valueTypeRef) {
        Object object = redisTemplate.opsForValue().get(key);
        if (object == null){
            return null;
        }
        String jsonStr = JsonUtil.obj2String(object);
        return JsonUtil.string2Obj(jsonStr,valueTypeRef);
    }
}

